﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Modules.Project.Repositories;
using PmSoft;
using PmSoft.ApplicationContext;
using PmSoft.Exceptions;

namespace Modules.Project
{
    [UseDI(ServiceLifetime.Scoped)]
    public class ProjectGuaranteeIncomeService
    {
        private readonly ProjectGuaranteeIncomeRepository repository;
        private readonly IApplicationContext applicationContext;
        private readonly ProjectGuaranteePaymentService projectGuaranteePaymentService;
        private readonly ILogger logger;

        public ProjectGuaranteeIncomeService(ProjectGuaranteeIncomeRepository repository, IApplicationContext applicationContext, ProjectGuaranteePaymentService projectGuaranteePaymentService, ILogger<ProjectGuaranteeIncomeService> logger)
        {
            this.repository = repository;
            this.applicationContext = applicationContext;
            this.projectGuaranteePaymentService = projectGuaranteePaymentService;
            this.logger = logger;
        }

        public ProjectGuaranteeIncome? GetProjectGuaranteeIncome(int id)
        {
            return repository.Get(id);
        }

        public IEnumerable<ProjectGuaranteeIncome> GetProjectGuaranteeIncomes(IEnumerable<int> ids)
        {
            return repository.PopulateEntitiesByEntityIds(ids);
        }

        public void Create(ProjectGuaranteeIncome entity)
        {
            var payment = projectGuaranteePaymentService.GetProjectGuaranteePaymentByProjectId(entity.ProjectId) ?? throw new BusinessException("该项目缴存信息不存在");
            if (payment.GuaranteeAccountType == 保证金类型.保证金账户)
            {
                payment.Balance += entity.Amount ?? 0;
            }
            try
            {
                applicationContext.Transaction.Begin();
                projectGuaranteePaymentService.Update(payment);
                repository.Insert(entity);
                applicationContext.Transaction.Complete();
            }
            catch (Exception ex)
            {
                applicationContext.Transaction.Abort();
                logger.LogError("添加收支信息失败", ex.Message);
                throw new BusinessException("添加收支信息失败");
            }
        }

        public void Update(ProjectGuaranteeIncome entity)
        {
            repository.Update(entity);
        }

        public IPagedList<ProjectGuaranteeIncome> GetProjectGuaranteeIncomes(ProjectGuaranteeIncomeQuery query, int pageIndex, int pageSize)
        {
            return repository.GetProjectGuaranteeIncomes(query, pageIndex, pageSize);
        }

        public void Delete(int id)
        {
            var entity = repository.Get(id) ?? throw new BusinessException("收入信息不存在");
            var payment = projectGuaranteePaymentService.GetProjectGuaranteePaymentByProjectId(entity.ProjectId) ?? throw new BusinessException("该项目缴存信息不存在");
            if (payment.GuaranteeAccountType == 保证金类型.保证金账户)
            {
                payment.Balance -= entity.Amount ?? 0;
                //if (payment.Balance < 0) throw new BusinessException("保证金缴纳账户的余额不足，无法删除");
            }
            try
            {
                applicationContext.Transaction.Begin();
                projectGuaranteePaymentService.Update(payment);
                repository.Delete(entity);
                applicationContext.Transaction.Complete();
            }
            catch (Exception ex)
            {
                applicationContext.Transaction.Abort();
                logger.LogError("删除收支信息失败", ex.Message);
                throw new BusinessException("删除收支信息失败");
            }
        }

        public void Deleted(IEnumerable<int> ids)
        {
            foreach (int id in ids)
            {
                Delete(id);
            }
        }
    }
}